[IA64] This patch fixes dom0 no VGA console bug.
authorawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Mon, 5 Jun 2006 20:21:37 +0000 (14:21 -0600)
committerawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Mon, 5 Jun 2006 20:21:37 +0000 (14:21 -0600)
After enabling dom0_vp mode, we lost the VGA console.
The reason is that VGA frame buffer(0xa0000-0xc0000) was set
to conventional memory not IO in dom0's p2m table.

Low conventional memory ranges are also given MDT entries for
dom0 to allow Linux to properly detect whether VGA is present.

Signed-off-by: Zhang xiantao <xiantao.zhang@intel.com>
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
xen/arch/ia64/xen/dom_fw.c
xen/arch/ia64/xen/mm.c
xen/include/asm-ia64/mm.h

index 8cd368d10048be249900e6d0d8996977386d27d2..2b7855c9c6f11b439e8d60d7875ecc5e9bccb230 100644 (file)
@@ -760,6 +760,38 @@ dom_fw_dom0_passthrough(efi_memory_desc_t *md, void *arg__)
     return 0;
 }
 
+/*
+ * Create dom0 MDT entries for conventional memory below 1MB.  Without
+ * this Linux will assume VGA is present because 0xA0000 will always
+ * be either a hole in the MDT or an I/O region via the passthrough.
+ */
+static int
+dom_fw_dom0_lowmem(efi_memory_desc_t *md, void *arg__)
+{
+    struct dom0_passthrough_arg* arg = (struct dom0_passthrough_arg*)arg__;
+    u64 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+
+    BUG_ON(md->type != EFI_CONVENTIONAL_MEMORY);
+
+    if (md->phys_addr >= 1*MB)
+        return 0;
+
+    if (end > 1*MB)
+        end = 1*MB;
+
+    arg->md->type = md->type;
+    arg->md->pad = 0;
+    arg->md->phys_addr = md->phys_addr;
+    arg->md->virt_addr = 0;
+    arg->md->num_pages = (end - md->phys_addr) >> EFI_PAGE_SHIFT;
+    arg->md->attribute = md->attribute;
+    print_md(arg->md);
+
+    (*arg->i)++;
+    arg->md++;
+    return 0;
+}
+
 static int
 efi_mdt_cmp(const void *a, const void *b)
 {
@@ -1051,6 +1083,8 @@ dom_fw_init (struct domain *d, const char *args, int arglen, char *fw_mem, int f
                                             dom_fw_dom0_passthrough, &arg);
                        efi_memmap_walk_type(EFI_MEMORY_MAPPED_IO_PORT_SPACE,
                                             dom_fw_dom0_passthrough, &arg);
+                       efi_memmap_walk_type(EFI_CONVENTIONAL_MEMORY,
+                                            dom_fw_dom0_lowmem, &arg);
                }
                else MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
 
@@ -1164,9 +1198,13 @@ dom_fw_init (struct domain *d, const char *args, int arglen, char *fw_mem, int f
                                }
                        }
                }
-               // work around for legacy device driver.
-               for (addr = 0; addr < 1 * MB; addr += PAGE_SIZE) {
-                       assign_new_domain0_page(d, addr);
+               // Map low-memory holes & unmapped MMIO for legacy drivers
+               for (addr = 0; addr < 1*MB; addr += PAGE_SIZE) {
+                       if (domain_page_mapped(d, addr))
+                               continue;
+                                       
+                       if (efi_mmio(addr, PAGE_SIZE))
+                               assign_domain_mmio_page(d, addr, PAGE_SIZE);
                }
                d->arch.physmap_built = 1;
        }
index e0a2131d63319daa085ef50e0ac4813d7bf4f859..b33bbf4ead5e3e8fc7c5f862613ea176048be095 100644 (file)
@@ -579,7 +579,7 @@ assign_domain_same_page(struct domain *d,
     }
 }
 
-static int
+int
 efi_mmio(unsigned long physaddr, unsigned long size)
 {
     void *efi_map_start, *efi_map_end;
@@ -968,6 +968,17 @@ domain_page_flush(struct domain* d, unsigned long mpaddr,
 {
     domain_flush_vtlb_all();
 }
+
+int
+domain_page_mapped(struct domain* d, unsigned long mpaddr)
+{
+    pte_t * pte;
+
+    pte=lookup_noalloc_domain_pte(d, mpaddr);
+    if(!pte_none(*pte))
+       return 1;
+    return 0;
+}
 #endif
 
 /* Flush cache of domain d.  */
index 215e844d2a98e73d0c7d9d95fe259f7a1e9c09e9..24e62e2b7c2b883c4c1384f2dd9e85447a3b48d6 100644 (file)
@@ -433,6 +433,8 @@ extern unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr);
 #ifdef CONFIG_XEN_IA64_DOM0_VP
 extern unsigned long assign_domain_mmio_page(struct domain *d, unsigned long mpaddr, unsigned long size);
 extern unsigned long assign_domain_mach_page(struct domain *d, unsigned long mpaddr, unsigned long size, unsigned long flags);
+int domain_page_mapped(struct domain *d, unsigned long mpaddr);
+int efi_mmio(unsigned long physaddr, unsigned long size);
 extern unsigned long __lookup_domain_mpa(struct domain *d, unsigned long mpaddr);
 extern unsigned long ____lookup_domain_mpa(struct domain *d, unsigned long mpaddr);
 extern unsigned long do_dom0vp_op(unsigned long cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3);